﻿using System;
using System.Collections.Generic;
using System.Data;
using NUnit.Framework;

namespace Salient.Data.Tests
{
    [TestFixture]
    public class ListDataReaderFixture
    {
        private static IList<DataObj2> DataSource()
        {
            var returnValue = new List<DataObj2>();
            returnValue.Add(new DataObj2
                                {
                                    BooleanProp = false,
                                    StringProp = "stringProp",
                                    ByteProp = 1,
                                    CharProp = 'c',
                                    DateTimeProp = new DateTime(2007, 12, 18),
                                    DecimalProp = (decimal) 100.1,
                                    DoubleProp = 100.2,
                                    FloatProp = (float) 100.3,
                                    GuidProp = new Guid("{C14E0CFE-0FFC-484c-A695-DB80D6F4FFD4}"),
                                    Int16Prop = 5,
                                    Int32Prop = 6,
                                    Int64Prop = 7,
                                    NullProp = null
                                });


            return returnValue;
        }

        [Test, ExpectedException(typeof (NotImplementedException))]
        public void Calling_Depth()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            int d = r.Depth;
        }

        [Test]
        public void Calling_FieldCount()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            Assert.AreEqual(13, r.FieldCount);
        }

        [Test]
        public void Calling_GetBoolean()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            Assert.AreEqual(false, r.GetBoolean(0));
            Assert.IsInstanceOf(typeof (bool), r.GetBoolean(0));
        }

        [Test]
        public void Calling_GetByte()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            Assert.AreEqual(1, r.GetByte(2));
            Assert.IsInstanceOf(typeof (byte), r.GetByte(2));
        }

        [Test, ExpectedException(typeof (NotImplementedException))]
        public void Calling_GetBytes()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            int i = 0;
            long fieldOffset = 0;
            byte[] buffer = null;
            int bufferOffset = 0;
            int length = 0;
            r.GetBytes(i, fieldOffset, buffer, bufferOffset, length);
        }

        [Test]
        public void Calling_GetChar()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetChar(3);
            Assert.AreEqual('c', value);
            Assert.IsInstanceOf(typeof (char), value);
        }

        [Test, ExpectedException(typeof (NotImplementedException))]
        public void Calling_GetChars()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            int i = 0;
            long fieldOffset = 0;
            char[] buffer = null;
            int bufferOffset = 0;
            int length = 0;
            r.GetChars(i, fieldOffset, buffer, bufferOffset, length);
        }

        [Test, ExpectedException(typeof (NotImplementedException))]
        public void Calling_GetData()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            r.GetData(9);
        }

        [Test]
        public void Calling_GetDataTypeName()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            string value = r.GetDataTypeName(0);
            Assert.AreEqual("Boolean", value);
        }

        [Test]
        public void Calling_GetDateTime()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetDateTime(4);
            Assert.AreEqual(new DateTime(2007, 12, 18), value);
            Assert.IsInstanceOf(typeof (DateTime), value);
        }

        [Test]
        public void Calling_GetDecimal()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetDecimal(5);
            Assert.AreEqual((decimal) 100.1, value);
            Assert.IsInstanceOf(typeof (decimal), value);
        }

        [Test]
        public void Calling_GetDouble()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetDouble(6);
            Assert.AreEqual(100.2, value);
            Assert.IsInstanceOf(typeof (double), value);
        }

        [Test]
        public void Calling_GetFieldType()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            Type type = r.GetFieldType(0);
            Assert.AreEqual(typeof (bool), type);
        }

        [Test]
        public void Calling_GetFloat()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetFloat(7);
            Assert.AreEqual((float) 100.3, value);
            Assert.IsInstanceOf(typeof (float), value);
        }

        [Test]
        public void Calling_GetGuid()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetGuid(8);
            Assert.AreEqual(new Guid("{C14E0CFE-0FFC-484c-A695-DB80D6F4FFD4}"), value);
            Assert.IsInstanceOf(typeof (Guid), value);
        }

        [Test]
        public void Calling_GetInt16()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetInt16(9);
            Assert.AreEqual((Int16) 5, value);
            Assert.IsInstanceOf(typeof (Int16), value);
        }

        [Test]
        public void Calling_GetInt32()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetInt32(10);
            Assert.AreEqual(6, value);
            Assert.IsInstanceOf(typeof (Int32), value);
        }

        [Test]
        public void Calling_GetInt64()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetInt64(11);
            Assert.AreEqual((Int64) 7, value);
            Assert.IsInstanceOf(typeof (Int64), value);
        }

        [Test]
        public void Calling_GetName()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            string result = r.GetName(0);
            Assert.AreEqual("BooleanProp", result);
        }

        [Test]
        public void Calling_GetOrdinal()
        {
            var r = new ListDataReader<DataObj2>(DataSource());

            Assert.AreEqual(0, r.GetOrdinal("BooleanProp"));
        }


        [Test]
        public void Calling_GetSchemaTable()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            object result = r.GetSchemaTable();
            Assert.IsInstanceOf(typeof (DataTable), result);
            var dt = (DataTable) result;
            Assert.AreEqual(13, dt.Columns.Count);

            Assert.AreEqual(typeof (bool), dt.Columns[0].DataType);
            Assert.AreEqual(typeof (string), dt.Columns[1].DataType);
            Assert.AreEqual(typeof (Byte), dt.Columns[2].DataType);
            Assert.AreEqual(typeof (Char), dt.Columns[3].DataType);
            Assert.AreEqual(typeof (DateTime), dt.Columns[4].DataType);
            Assert.AreEqual(typeof (decimal), dt.Columns[5].DataType);
            Assert.AreEqual(typeof (double), dt.Columns[6].DataType);
            Assert.AreEqual(typeof (float), dt.Columns[7].DataType);
            Assert.AreEqual(typeof (Guid), dt.Columns[8].DataType);
            Assert.AreEqual(typeof (Int16), dt.Columns[9].DataType);
            Assert.AreEqual(typeof (Int32), dt.Columns[10].DataType);
            Assert.AreEqual(typeof (Int64), dt.Columns[11].DataType);
            Assert.AreEqual(typeof (string), dt.Columns[12].DataType);
            Assert.AreEqual("BooleanProp", dt.Columns[0].ColumnName);
            Assert.AreEqual("StringProp", dt.Columns[01].ColumnName);
            Assert.AreEqual("ByteProp", dt.Columns[02].ColumnName);
            Assert.AreEqual("CharProp", dt.Columns[03].ColumnName);
            Assert.AreEqual("DateTimeProp", dt.Columns[04].ColumnName);
            Assert.AreEqual("DecimalProp", dt.Columns[05].ColumnName);
            Assert.AreEqual("DoubleProp", dt.Columns[06].ColumnName);
            Assert.AreEqual("FloatProp", dt.Columns[07].ColumnName);
            Assert.AreEqual("GuidProp", dt.Columns[08].ColumnName);
            Assert.AreEqual("Int16Prop", dt.Columns[09].ColumnName);
            Assert.AreEqual("Int32Prop", dt.Columns[10].ColumnName);
            Assert.AreEqual("Int64Prop", dt.Columns[11].ColumnName);
            Assert.AreEqual("NullProp", dt.Columns[12].ColumnName);
        }

        [Test]
        public void Calling_GetString()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetString(1);
            Assert.AreEqual("stringProp", value);
            Assert.IsInstanceOf(typeof (string), value);
        }

        [Test]
        public void Calling_GetValue()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            object value = r.GetValue(1);
            Assert.AreEqual("stringProp", value);
            Assert.IsInstanceOf(typeof (string), value);
        }

        [Test]
        public void Calling_GetValues()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            var values = new object[13];
            int result = r.GetValues(values);
            Assert.AreEqual(13, result);

            values = new object[15];
            result = r.GetValues(values);
            Assert.AreEqual(13, result);

            values = new object[5];
            result = r.GetValues(values);
            Assert.AreEqual(5, result);
        }

        [Test]
        public void Calling_IsClosed()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            Assert.IsFalse(r.IsClosed);
            r.Close();
            Assert.IsTrue(r.IsClosed);
        }

        [Test]
        public void Calling_IsDBNull()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.Read();
            Assert.IsTrue(r.IsDBNull(12));
        }

        [Test, ExpectedException(typeof (NotImplementedException))]
        public void Calling_NextResult()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            r.NextResult();
        }

        [Test]
        public void Calling_RecordsAffected()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            Assert.AreEqual(-1, r.RecordsAffected);
            r.Read();
        }

        [Test]
        public void Get_Name()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            Assert.AreEqual("BooleanProp", r.GetName(0));
        }

        [Test]
        public void ReadTwice()
        {
            var r = new ListDataReader<DataObj2>(DataSource());
            Assert.IsTrue(r.Read());
            Assert.IsFalse(r.Read(), "should be finished");
        }
    }
}